<template>
  <el-dialog
    class="flow-dialog"
    title="字典"
    :model-value="visible"
    width="30%"
    destroy-on-close
    center
    modal
    :close-on-click-modal="false"
    :show-close="false"
  >
    <el-form
      ref="formRef"
      :model="dictForm"
      :rules="rules"
      label-width="110"
      inline-message
      :status-icon="true"
    >
      <el-form-item label="上级字典" prop="parentId">
        <el-tree-select
          v-model="dictForm.parentId"
          node-key="id"
          :props="{
            value: 'id',
            label: 'label',
            children: 'children',
          }"
          highlight-current
          check-strictly
          lazy
          :disabled="!add"
          :load="loadDictTree"
          :default-expanded-keys="ancestors"
        />
      </el-form-item>
      <el-form-item label="字典名称" prop="label">
        <el-input
          v-model="dictForm.label"
          placeholder="请输入字典名称"
          clearable
          maxlength="20"
        />
      </el-form-item>
      <el-form-item label="字典代码" prop="code">
        <el-input
          v-model="dictForm.code"
          placeholder="请输入字典代码"
          clearable
          maxlength="20"
        />
      </el-form-item>
      <el-form-item label="字典描述" prop="description">
        <el-input
          v-model="dictForm.description"
          placeholder="请输入字典描述"
          :rows="2"
          type="textarea"
          clearable
        />
      </el-form-item>
      <el-form-item label="排序" prop="sort">
        <el-input-number v-model="dictForm.sort" :min="1" />
      </el-form-item>
      <el-form-item label="是否可编辑" prop="editable">
        <el-switch
          v-model="dictForm.editable"
          inline-prompt
          active-text="是"
          inactive-text="否"
          style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button
          type="primary"
          :loading="loading"
          :icon="useRenderIcon('material-symbols:check')"
          @click="submit()"
        >
          保存
        </el-button>
        <el-button
          type="danger"
          :loading="loading"
          :icon="useRenderIcon('material-symbols:close')"
          @click="close()"
        >
          关闭
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts">
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { FormInstance } from "element-plus";
import { DictModel } from "@/api/model/dictModel";
import { defineComponent, reactive, ref } from "vue";
import { message } from "@/utils/message";
import { checkCode, childrenById, saveDict } from "@/api/dict";

const loading = ref(false);
const visible = ref(false);
const add = ref(true);
const formRef = ref<FormInstance>();
const dictForm = ref<DictModel>({});
const ancestors = ref([]);
const rootDict = ref<DictModel[]>([
  {
    id: "0",
    label: "根节点",
  },
]);

const validCode = async (rule, value, callback) => {
  if (value == null || value === "") {
    callback(new Error("请输入字典代码"));
  } else {
    if (!/\w{4,20}/.test(value)) {
      callback(
        new Error(
          "字典代码只能使用英文，数字和下划线 _ ，且必须在4到20个字符之间"
        )
      );
    } else {
      let usable;
      if (add.value) {
        usable = await checkCode(value);
      } else {
        usable = await checkCode(value, dictForm.value.id);
      }
      if (!usable) {
        callback(new Error("字典代码已被使用"));
      }
    }
  }
  callback();
};

const rules = reactive({
  label: [
    { required: true, message: "请输入字典名称", trigger: "blur" },
    {
      min: 2,
      max: 20,
      message: "字典名称必须在2-20个字符之间",
      trigger: "blur",
    },
  ],
  code: [
    { required: true, message: "请输入字典代码", trigger: "blur" },
    { validator: validCode, trigger: "blur" },
  ],
  parentId: [{ required: true, message: "请选择上级字典", trigger: "blur" }],
  sort: [{ required: true, message: "请输入排序", trigger: "blur" }],
});

const close = () => {
  visible.value = false;
};
const openAdd = () => {
  dictForm.value = {
    state: true,
    editable: true,
  };
  add.value = true;
  visible.value = true;
  ancestors.value = [];
};
const openEdit = (form: DictModel) => {
  dictForm.value = {
    id: form.id,
    parentId: form.parentId + "",
    code: form.code,
    label: form.label,
    state: form.state,
    sort: form.sort,
    description: form.description,
    editable: form.editable,
  } as DictModel;
  add.value = false;
  visible.value = true;
  ancestors.value = form.ancestors.split(",");
};
const loadDictTree = async (node, resolve) => {
  if (node && node.level === 0) {
    resolve(rootDict.value);
  } else {
    const data = await childrenById(node.data.id);
    resolve(data);
  }
};

export default defineComponent({
  setup(props, context) {
    function reloadList(pid) {
      context.emit("reload", pid);
    }
    function submit() {
      formRef.value.validate(valid => {
        if (valid) {
          loading.value = true;
          saveDict(dictForm.value)
            .then(res => {
              if (res) {
                message("保存成功", { type: "success" });
                reloadList(res.parentId);
                close();
              } else {
                message("保存失败", { type: "error" });
              }
            })
            .catch(e => {
              message(e.message, { type: "error" });
            })
            .finally(() => {
              loading.value = false;
            });
        }
      });
    }
    return {
      formRef,
      rules,
      loading,
      visible,
      add,
      dictForm,
      ancestors,
      close,
      submit,
      useRenderIcon,
      loadDictTree,
    };
  },
});

export function initDictDialog() {
  return {
    openAdd,
    openEdit,
  };
}
</script>
<style scoped></style>
